package com.aierjun.camera.record;

import android.app.Activity;
import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;

import com.aierjun.camera.AppInit;
import com.aierjun.camera.R;
import com.aierjun.camera.common.ViewParamsCallback;
import com.aierjun.camera.manager.CameraManager;
import com.aierjun.camera.sensor.SensorControler;
import com.aierjun.camera.utils.FileUtil;
import com.aierjun.camera.widget.FocusImageView;
import com.aierjun.camera.widget.RecordCameraView;

import java.io.File;
import java.io.IOException;


public class RecordVideoManager implements RecordVideoManagerInterface {


    private SensorControler mSensorControler;
    private RecordCameraView recordCameraView;
    private FocusImageView mFocusImageView;
    private SeekBar zoom_seekbar;
    private int cameraWidth, cameraHeight, controllerHeight;
    private RelativeLayout controller_rl;
    private ImageView shutterImageView;
    private ImageView backImageView;
    private ImageView mBtnLenses;
    private ImageView btnflashlight;
    private ImageView mOkImageView;

    private Surface surface;
    private TextureView textureView;
    private MediaPlayer mediaPlayer;

    private boolean isRecord = false;
    private String mVideoPath;

    private RelativeLayout.LayoutParams paramsController;

    private RelativeLayout.LayoutParams paramsTexture;

    private SaveCallBackPathLister saveCallBackPathLister;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

        }
    };

    private Activity activity;
    private static RecordVideoManager self;

    public static RecordVideoManager getInstance(Activity activity) {
        if (self == null)
            self = new RecordVideoManager(activity);
        return self;
    }

    public RecordVideoManager(Activity activity) {
        this.activity = activity;
    }

    public RecordVideoManager initCamera(RecordCameraView cameraView) {
        recordCameraView = cameraView;
        cameraView.bindActivity(activity);
        cameraView.setOnCameraPrepareListener(new RecordCameraView.OnCameraPrepareListener() {
            @Override
            public void onPrepare(CameraManager.CameraDirection cameraDirection) {
                //在这里相机已经准备好 可以获取maxZoom
                zoom_seekbar.setMax(recordCameraView.getMaxZoom());
                if (cameraDirection == CameraManager.CameraDirection.CAMERA_BACK) {
                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            int screenWidth = AppInit.mScreenWidth;
                            Point point = new Point(screenWidth / 2, screenWidth / 2);
                            onCameraFocus(point);
                        }
                    }, 800);
                }
            }
        });
        cameraView.setSwitchCameraCallBack(new RecordCameraView.SwitchCameraCallBack() {
            @Override
            public void switchCamera(boolean isSwitchFromFront) {
                if (isSwitchFromFront) {
                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            int screenWidth = AppInit.mScreenWidth;
                            Point point = new Point(screenWidth / 2, screenWidth / 2);
                            onCameraFocus(point);
                        }
                    }, 300);
                }
            }
        });

        recordCameraView.setViewParamsCallback(new ViewParamsCallback() {
            @Override
            public void callBackParams(ViewGroup.LayoutParams params) {
//                Log.d("Ani",SweetApplication.mScreenHeight + " ------------ " + params.height);
                cameraWidth = params.width;
                cameraHeight = params.height;
                controllerHeight = AppInit.mScreenHeight - params.height;
                if (controllerHeight < 400)
                    controllerHeight = 400;
                if (controller_rl != null) {
                    if (paramsController == null) {
                        paramsController = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, controllerHeight);
                        paramsController.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                    }
                    controller_rl.setBackgroundColor(activity.getResources().getColor(R.color.font4));
                    controller_rl.setLayoutParams(paramsController);
                    controller_rl.setVisibility(View.VISIBLE);
                }
                if (textureView != null) {
//                    Log.d("Ani", "-------------------------");
                    if (paramsTexture == null) {
                        paramsTexture = new RelativeLayout.LayoutParams(cameraWidth, cameraHeight);
                        textureView.setLayoutParams(paramsTexture);
                        textureView.setVisibility(View.GONE);
                    }
                }
            }
        });
        return this;
    }

    public RecordVideoManager initFocusImageView(FocusImageView focusImageView) {
        mFocusImageView = focusImageView;
        return this;
    }

    public RecordVideoManager initControllerRLChildView(RelativeLayout controller_rl, ImageView backImageView, ImageView shutterImageView, ImageView btn_lenses, ImageView btn_flashlight, ImageView okImageView) {
        this.controller_rl = controller_rl;
        this.backImageView = backImageView;
        this.shutterImageView = shutterImageView;
        this.mBtnLenses = btn_lenses;
        this.btnflashlight = btn_flashlight;
        this.mOkImageView = okImageView;

        backImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isRecord)
                    MediaRecordConfig.getInstance().stopMedia(activity);
                if (textureView != null && textureView.getVisibility() == View.VISIBLE) {
                    textureView.setVisibility(View.GONE);
                    mOkImageView.setVisibility(View.GONE);
                    mSensorControler.unlockFocus();
                    onStart();
                    if (mediaPlayer == null) return;
                    mediaPlayer.stop();
                    mediaPlayer.reset();
                    mediaPlayer.release();
                    mediaPlayer = null;
                } else
                    activity.finish();
            }
        });

        okImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textureView.setVisibility(View.GONE);
                if (mediaPlayer != null) {
                    mediaPlayer.stop();
                    mediaPlayer.reset();
                    mediaPlayer.release();
                    mediaPlayer = null;
                }
                //完成操作
                if (saveCallBackPathLister != null)
                    saveCallBackPathLister.callBackPath(mVideoPath);
                if (activity != null && !activity.isFinishing())
                    activity.finish();
            }
        });

        shutterImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //录制按钮
                if (!isRecord) {
                    mBtnLenses.setVisibility(View.GONE);
                    mVideoPath = Environment.getExternalStorageDirectory() + File.separator + FileUtil.FOLDER + File.separator + System.currentTimeMillis() + ".mp4";
                    isRecord = MediaRecordConfig.getInstance().mediaRecorderSet(recordCameraView, mVideoPath, new MediaRecorder.OnErrorListener() {
                        @Override
                        public void onError(MediaRecorder mr, int what, int extra) {
                            Log.e("Ani", extra + " Record ERROR!");
                        }
                    }).startMedia();
                    Log.d("Ani", "正在录制...");
                } else {
                    MediaRecordConfig.getInstance().stopMedia(activity);
                    isRecord = false;
                    Log.d("Ani", "结束录制...");
                    textureView.setVisibility(View.VISIBLE);
                    mOkImageView.setVisibility(View.VISIBLE);
                    mSensorControler.lockFocus();
                    onStop();
                    mBtnLenses.setVisibility(View.VISIBLE);
                    new MyMediaPlayThread().start();
                }
            }
        });
        btn_lenses.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                recordCameraView.switchCamera();
            }
        });
        btnflashlight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                recordCameraView.switchFlashMode();
                CameraManager.FlashLigthStatus flashLigthStatus = CameraManager.getInstance(activity).getLightStatus();
                if (flashLigthStatus == CameraManager.FlashLigthStatus.LIGHT_AUTO) {
                    btnflashlight.setImageDrawable(activity.getResources().getDrawable(R.drawable.camera_icon_flashlight_auto));
                } else if (flashLigthStatus == CameraManager.FlashLigthStatus.LIGHT_ON) {
                    btnflashlight.setImageDrawable(activity.getResources().getDrawable(R.drawable.camera_icon_flashlight_on));
                } else if (flashLigthStatus == CameraManager.FlashLigthStatus.LIGTH_OFF) {
                    btnflashlight.setImageDrawable(activity.getResources().getDrawable(R.drawable.camera_icon_flashlight_off));
                }
            }
        });
        return this;
    }

    public RecordVideoManager initSensorControler() {
        mSensorControler = SensorControler.getInstance();

        mSensorControler.setCameraFocusListener(new SensorControler.CameraFocusListener() {
            @Override
            public void onFocus() {
                int screenWidth = AppInit.mScreenWidth;
                Point point = new Point(screenWidth / 2, screenWidth / 2);

                onCameraFocus(point);
            }
        });
        return this;
    }

    public RecordVideoManager initZoomSeekBar(SeekBar zoom_seekbar) {
        this.zoom_seekbar = zoom_seekbar;
        //禁止手动操作seekbar
        zoom_seekbar.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });
        return this;
    }

    public RecordVideoManager initTextureView(TextureView textureView) {
        this.textureView = textureView;
        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
                surface = new Surface(surfaceTexture);
//                Log.d("Ani", "--------onSurfaceTextureAvailable----------");
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                surface = null;
                if (mediaPlayer != null) {
                    mediaPlayer.stop();
                    mediaPlayer.release();
                }
                return true;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {

            }
        });
        return this;
    }


    /**
     * 相机对焦  默认不需要延时
     *
     * @param point
     */
    private void onCameraFocus(final Point point) {
        onCameraFocus(point, false);
    }

    /**
     * 相机对焦
     *
     * @param point
     * @param needDelay 是否需要延时
     */
    private void onCameraFocus(final Point point, boolean needDelay) {
        long delayDuration = needDelay ? 300 : 0;

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (!mSensorControler.isFocusLocked()) {
                    if (recordCameraView.onFocus(point, autoFocusCallback)) {
                        mSensorControler.lockFocus();
                        mFocusImageView.startFocus(point);

                    }
                }
            }
        }, delayDuration);
    }

    private final Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            //聚焦之后根据结果修改图片
            if (success) {
                mFocusImageView.onFocusSuccess();
            } else {
                //聚焦失败显示的图片，由于未找到合适的资源，这里仍显示同一张图片
                mFocusImageView.onFocusFailed();
            }
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //一秒之后才能再次对焦
                    mSensorControler.unlockFocus();
                }
            }, 1000);
        }
    };


    @Override
    public void onStart() {
        mSensorControler.onStart();

        if (recordCameraView != null) {
            recordCameraView.onStart();
        }
    }

    @Override
    public void onStop() {
        mSensorControler.onStop();
        if (recordCameraView != null) {
            recordCameraView.onStop();
        }
    }

    @Override
    public void onDestroy() {
        recordCameraView.releaseCamera();
    }


    /**
     * 记录是拖拉照片模式还是放大缩小照片模式
     */

    private static final int MODE_INIT = 0;
    /**
     * 放大缩小照片模式
     */
    private static final int MODE_ZOOM = 1;
    private int mode = MODE_INIT;// 初始状态

    private float startDis;

    public boolean onTouchEvent(MotionEvent event) {
/** 通过与运算保留最后八位 MotionEvent.ACTION_MASK = 255 */
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {//回复录制的视频的时候不能触摸对焦
            return true;
        }
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            // 手指压下屏幕
            case MotionEvent.ACTION_DOWN:
                mode = MODE_INIT;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                //如果mZoomSeekBar为null 表示该设备不支持缩放 直接跳过设置mode Move指令也无法执行
                if (zoom_seekbar == null) return true;
                //移除token对象为mZoomSeekBar的延时任务
                mHandler.removeCallbacksAndMessages(zoom_seekbar);
//                mZoomSeekBar.setVisibility(View.VISIBLE);
                zoom_seekbar.setVisibility(View.GONE);

                mode = MODE_ZOOM;
                /** 计算两个手指间的距离 */
                startDis = spacing(event);
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == MODE_ZOOM) {
                    zoom_seekbar.setVisibility(View.VISIBLE);
                    //只有同时触屏两个点的时候才执行
                    if (event.getPointerCount() < 2) return true;
                    float endDis = spacing(event);// 结束距离
                    //每变化10f zoom变1
                    int scale = (int) ((endDis - startDis) / 10f);
                    if (scale >= 1 || scale <= -1) {
                        int zoom = recordCameraView.getZoom() + scale;
                        //zoom不能超出范围
                        if (zoom > recordCameraView.getMaxZoom())
                            zoom = recordCameraView.getMaxZoom();
                        if (zoom < 0) zoom = 0;
                        recordCameraView.setZoom(zoom);
                        zoom_seekbar.setMax(recordCameraView.getMaxZoom());
                        zoom_seekbar.setProgress(zoom);
                        //将最后一次的距离设为当前距离
                        startDis = endDis;
                    }
                }
                break;
            // 手指离开屏幕
            case MotionEvent.ACTION_UP:
                if (mode != MODE_ZOOM) {
                    //设置聚焦
                    Point point = new Point((int) event.getX(), (int) event.getY());
                    onCameraFocus(point);
                } else {
                    //ZOOM模式下 在结束两秒后隐藏seekbar 设置token为mZoomSeekBar用以在连续点击时移除前一个定时任务
                    mHandler.postAtTime(new Runnable() {

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            zoom_seekbar.setVisibility(View.GONE);
                        }
                    }, zoom_seekbar, SystemClock.uptimeMillis() + 2000);
                }
                break;
        }
        return true;

    }

    @Override
    public void setSaveCallBackPathLister(SaveCallBackPathLister saveCallBackPathLister) {
        this.saveCallBackPathLister = saveCallBackPathLister;
    }


    /**
     * 两点的距离
     */
    private float spacing(MotionEvent event) {
        if (event == null) {
            return 0;
        }
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }


    class MyMediaPlayThread extends Thread {

        @Override
        public void run() {
            super.run();
            try {
                while (surface == null) {
                }
                if (mediaPlayer == null)
                    mediaPlayer = new MediaPlayer();
                mediaPlayer.setDataSource(mVideoPath);
                mediaPlayer.setSurface(surface);
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mediaPlayer.setLooping(true);
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mediaPlayer.start();
                    }
                });
                mediaPlayer.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
